
<html>
<head>
<title>/home/matthias/java/jsresources/examples/src/AudioConverter.java</title>
<meta name="generator" content="java2html 0.9.2">
<meta name="date" content="2005-01-30T18:36:12+00:00">
</head>

<body bgcolor="#FFFFFF">
<pre width="80"><font color="#B22222">/*
 *	AudioConverter.java
 *
 *	This file is part of jsresources.org
 */</font>

<font color="#B22222">/*
 * Copyright (c) 1999 - 2004 by Matthias Pfisterer
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */</font>

<font color="#B22222">/*
|&lt;---            this code is formatted to fit into 80 columns             ---&gt;|
*/</font>

<font color="#228B22">import java.io.IOException;</font>
<font color="#228B22">import java.io.File;</font>

<font color="#228B22">import javax.sound.sampled.AudioFileFormat;</font>
<font color="#228B22">import javax.sound.sampled.AudioFormat;</font>
<font color="#228B22">import javax.sound.sampled.AudioInputStream;</font>
<font color="#228B22">import javax.sound.sampled.AudioSystem;</font>
<font color="#228B22">import javax.sound.sampled.UnsupportedAudioFileException;</font>

<font color="#B22222">/*	If the compilation fails because this class is not available,
	get gnu.getopt from the URL given in the comment below.
*/</font>
<font color="#228B22">import gnu.getopt.Getopt;</font>


<font color="#B22222">/**	&lt;titleabbrev&gt;AudioConverter&lt;/titleabbrev&gt;
	&lt;title&gt;Converting audio files to different encodings, sample size, channels, sample rate&lt;/title&gt;

	&lt;formalpara&gt;&lt;title&gt;Purpose&lt;/title&gt;
	&lt;para&gt;Converts audio files, changing the sample rate of the
	audio data.&lt;/para&gt;
	&lt;/formalpara&gt;

	&lt;formalpara&gt;&lt;title&gt;Usage&lt;/title&gt;
	&lt;para&gt;
	&lt;cmdsynopsis&gt;
	&lt;command&gt;java AudioConverter&lt;/command&gt;
	&lt;arg choice="plain"&gt;&lt;option&gt;-h&lt;/option&gt;&lt;/arg&gt;
	&lt;/cmdsynopsis&gt;
	&lt;cmdsynopsis&gt;
	&lt;command&gt;java AudioConverter&lt;/command&gt;
	&lt;arg choice="plain"&gt;&lt;option&gt;-l&lt;/option&gt;&lt;/arg&gt;
	&lt;/cmdsynopsis&gt;
	&lt;cmdsynopsis&gt;
	&lt;command&gt;java AudioConverter&lt;/command&gt;
	&lt;arg&gt;&lt;option&gt;-c &lt;replaceable class="parameter"&gt;channels&lt;/replaceable&gt;&lt;/option&gt;&lt;/arg&gt;
	&lt;arg&gt;&lt;option&gt;-s &lt;replaceable class="parameter"&gt;sample_size&lt;/replaceable&gt;&lt;/option&gt;&lt;/arg&gt;
	&lt;arg&gt;&lt;option&gt;-e &lt;replaceable class="parameter"&gt;encoding&lt;/replaceable&gt;&lt;/option&gt;&lt;/arg&gt;
	&lt;arg&gt;&lt;option&gt;-f &lt;replaceable class="parameter"&gt;sample_rate&lt;/replaceable&gt;&lt;/option&gt;&lt;/arg&gt;
	&lt;arg&gt;&lt;option&gt;-t &lt;replaceable class="parameter"&gt;file_type&lt;/replaceable&gt;&lt;/option&gt;&lt;/arg&gt;
	&lt;group choice="opt"&gt;
	&lt;arg&gt;&lt;option&gt;-B&lt;/option&gt;&lt;/arg&gt;
	&lt;arg&gt;&lt;option&gt;-L&lt;/option&gt;&lt;/arg&gt;
	&lt;/group&gt;
	&lt;arg&gt;&lt;option&gt;-D&lt;/option&gt;&lt;/arg&gt;
	&lt;arg choice="plain"&gt;&lt;replaceable class="parameter"&gt;sourcefile&lt;/replaceable&gt;&lt;/arg&gt;
	&lt;arg choice="plain"&gt;&lt;replaceable class="parameter"&gt;targetfile&lt;/replaceable&gt;&lt;/arg&gt;
	&lt;/cmdsynopsis&gt;
	&lt;/para&gt;&lt;/formalpara&gt;

	&lt;formalpara&gt;&lt;title&gt;Parameters&lt;/title&gt;
	&lt;variablelist&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;option&gt;-h&lt;/option&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;prints usage information&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;option&gt;-l&lt;/option&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;lists available file types&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;channels&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the number of channels to convert to, for instance 1 for mono or 2 for stereo&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;sample_size&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the sample size in bits to convert to, for instance 8 for 8 bit samples&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;encoding&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the encoding name to convert to, for instance PCM_SIGNED, ULAW or VORBIS&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;sample_rate&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the sample rate to convert to, for instance 44100 or 8000. Fractional values are allowed, for instance 8192.76&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;file_type&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the file type to write the target file, for instance WAVE or AU.&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;sourcefile&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the file name of the audio file that should be read to get the source audio data&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;varlistentry&gt;
	&lt;term&gt;&lt;replaceable class="parameter"&gt;targetfile&lt;/replaceable&gt;&lt;/term&gt;
	&lt;listitem&gt;&lt;para&gt;the file name of the audio file that the converted audio data should be written to&lt;/para&gt;&lt;/listitem&gt;
	&lt;/varlistentry&gt;
	&lt;/variablelist&gt;
	&lt;/formalpara&gt;

	&lt;formalpara&gt;&lt;title&gt;Bugs, limitations&lt;/title&gt;
	&lt;para&gt;Sample rate conversion can only be handled natively
	by &lt;ulink url="http://www.tritonus.org/"&gt;Tritonus&lt;/ulink&gt;.
	If you want to do sample rate conversion with the
	Sun jdk1.3/1.4/1.5, you have to install Tritonus' sample rate converter.
	Converting number of channels and sample size is only partly supported
	by the Sun JDK. To get more options, install Tritonus's PCM2PCM converter.
	Both are part of the 'Tritonus miscellaneous' plug-in. See &lt;ulink url
	="http://www.tritonus.org/plugins.html"&gt;Tritonus Plug-ins&lt;/ulink&gt;.
	&lt;/para&gt;
	&lt;/formalpara&gt;

	&lt;formalpara&gt;&lt;title&gt;Source code&lt;/title&gt;
	&lt;para&gt;
	&lt;ulink url="AudioConverter.java.html"&gt;AudioConverter.java&lt;/ulink&gt;,
	&lt;ulink url="AudioCommon.java.html"&gt;AudioCommon.java&lt;/ulink&gt;,
	&lt;olink targetdocent="getopt"&gt;gnu.getopt.Getopt&lt;/olink&gt;
	&lt;/para&gt;
	&lt;/formalpara&gt;

*/</font>
<font color="#B22222">// IDEA: name for Florian's program: BatchAudioConverter</font>
<strong><font color="#4169E1"><a name="AudioConverter"></a>public class AudioConverter</font></strong>
{
	<font color="#B22222">/** Threshold for float comparisions.
		If the difference between two floats is smaller than DELTA, they
		are considered equal.
	 */</font>
	private static final float DELTA = 1E-9F;

	<font color="#B22222">/**	Flag for debugging messages.
	 *	If true, some messages are dumped to the console
	 *	during operation.	
	 */</font>
	private static boolean		DEBUG = false;


<strong><font color="#4169E1">	public static void main(String[] args)</font></strong>
		<font color="#4169E1">throws</font> UnsupportedAudioFileException, IOException
	{
		<font color="#B22222">/** The number of channels the audio data should be converted to.
			The value is initialized to -1. This is used to represent the
			condition that conversion of channels is not requested on the
			command line.
		*/</font>
		int nDesiredChannels = AudioSystem.NOT_SPECIFIED;

		<font color="#B22222">/** The sample size in bits the audio data should be converted to.
		*/</font>
		int nDesiredSampleSizeInBits = AudioSystem.NOT_SPECIFIED;

		<font color="#B22222">/** The encoding the audio data should be converted to.
		*/</font>
		AudioFormat.Encoding desiredEncoding = null;

		<font color="#B22222">/** The sample rate the audio data should be converted to.
		*/</font>
		float fDesiredSampleRate = AudioSystem.NOT_SPECIFIED;

		<font color="#B22222">/** The file type that should be used to write the audio data.
		*/</font>
		AudioFileFormat.Type desiredFileType = null;

		<font color="#B22222">/** The endianess the audio data should be converted to.
			This is only used if bIsEndianessDesired is true.
		*/</font>
		boolean bDesiredBigEndian = false;

		<font color="#B22222">/** Whether conversion of endianess is desired. This flag is
			necessary because the boolean variable bDesiredBigEndian
			has no 'unspecified' value to signal that endianess
			conversion is not desired.
		*/</font>
		boolean bIsEndianessDesired = false;

		<font color="#B22222">/*
		 * Parsing of command-line options takes place...
		 */</font>
		Getopt	g = new Getopt(<font color="#666666">"AudioConverter"</font>, args, <font color="#666666">"hlc:s:e:f:t:BLD"</font>);
		int	c;
		<font color="#4169E1">while</font> ((c = g.getopt()) != -1)
		{
			<font color="#4169E1">switch</font> (c)
			{
			<font color="#4169E1">case</font> 'h':
				printUsageAndExit();

			<font color="#4169E1">case</font> 'l':
				<font color="#B22222">// TODO: listSupportedEncodings();</font>
				AudioCommon.listSupportedTargetTypes();
				System.exit(0);

			<font color="#4169E1">case</font> 'c':
				nDesiredChannels = Integer.parseInt(g.getOptarg());
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 's':
				nDesiredSampleSizeInBits = Integer.parseInt(g.getOptarg());
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 'e':
				String strEncodingName = g.getOptarg();
				desiredEncoding = new AudioFormat.Encoding(strEncodingName);
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 'f':
				fDesiredSampleRate = Float.parseFloat(g.getOptarg());
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 't':
				String	strExtension = g.getOptarg();
				desiredFileType = AudioCommon.findTargetType(strExtension);
				<font color="#4169E1">if</font> (desiredFileType == null)
				{
					out(<font color="#666666">"Unknown target file type. Check with 'AudioConverter -l'."</font>);
					System.exit(1);
				}
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 'B':
				bDesiredBigEndian = true;
				bIsEndianessDesired = true;
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 'L':
				bDesiredBigEndian = true;
				bIsEndianessDesired = true;
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> 'D':
				DEBUG = true;
				<font color="#4169E1">break</font>;

			<font color="#4169E1">case</font> '?':
				printUsageAndExit();

<strong><font color="#FF0000">			default:</font></strong>
				out(<font color="#666666">"getopt() returned "</font> + c);
				<font color="#4169E1">break</font>;
			}
		}

		<font color="#B22222">/* We make shure that there are only two more arguments, which
		   we take as the input and output filenames. */</font>
		<font color="#4169E1">if</font> (args.length - g.getOptind() &lt; 2)
		{
			printUsageAndExit();
		}

		File inputFile = new File(args[g.getOptind()]);
		File outputFile = new File(args[g.getOptind() + 1]);

		<font color="#B22222">/* As default for the audio file type we use the one of the
		   source file. So we first have to find out about the source
		   file's properties.
		*/</font>
		AudioFileFormat		inputFileFormat = AudioSystem.getAudioFileFormat(inputFile);
		AudioFileFormat.Type	defaultFileType = inputFileFormat.getType();

		<font color="#B22222">/* Here, we are reading the source file.
		 */</font>
		AudioInputStream	stream = null;
		stream = AudioSystem.getAudioInputStream(inputFile);
		AudioFormat	format = stream.getFormat();
		<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"source format: "</font> + format);
		AudioFormat targetFormat = null;

		<font color="#B22222">/* To ease our job later, we fill the values of the AudioFormat
		   properties not required with the values of the source format.
		 */</font>
		<font color="#4169E1">if</font> (desiredEncoding == null)
		{
			desiredEncoding = format.getEncoding();
		}
		<font color="#4169E1">if</font> (fDesiredSampleRate == AudioSystem.NOT_SPECIFIED)
		{
			fDesiredSampleRate = format.getSampleRate();
		}
		<font color="#4169E1">if</font> (nDesiredSampleSizeInBits == AudioSystem.NOT_SPECIFIED)
		{
			nDesiredSampleSizeInBits = format.getSampleSizeInBits();
		}
		<font color="#4169E1">if</font> (nDesiredChannels == AudioSystem.NOT_SPECIFIED)
		{
			nDesiredChannels = format.getChannels();
		}
		<font color="#4169E1">if</font> (! bIsEndianessDesired)
		{
			bDesiredBigEndian = format.isBigEndian();
		}

		<font color="#B22222">/* Step 1: convert to PCM, if necessary.
		*/</font>
		<font color="#4169E1">if</font> (! AudioCommon.isPcm(format.getEncoding()))
		{
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"converting to PCM..."</font>);
			<font color="#B22222">/* The following is a heuristics: normally (but not always),
			   8 bit audio data are unsigned, while 16 bit data are signed.
			*/</font>
			AudioFormat.Encoding targetEncoding =
				(format.getSampleSizeInBits() == 8) ?
				AudioFormat.Encoding.PCM_UNSIGNED :
				AudioFormat.Encoding.PCM_SIGNED;
			stream = convertEncoding(targetEncoding, stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"stream: "</font> + stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"format: "</font> + stream.getFormat());

			<font color="#B22222">/* Here, we handle a special case: some compressed formats
			   do not state a sample size (but AudioSystem.NOT_SPECIFIED)
			   because its unknown how long
			   the samples are after decoding. If no sample size has been
			   requested with a command line option,
			   In this case, nDesiredSampleSizeInBits still has the value
			   AudioSystem.NOT_SPECIFIED despite the filling with default
			   values above.
			*/</font>
			<font color="#4169E1">if</font> (nDesiredSampleSizeInBits == AudioSystem.NOT_SPECIFIED)
			{
				nDesiredSampleSizeInBits = format.getSampleSizeInBits();
			}
		}

		<font color="#B22222">/* Step 2: convert number of channels, if necessary.
		*/</font>
		<font color="#4169E1">if</font> (stream.getFormat().getChannels() != nDesiredChannels)
		{
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"converting channels..."</font>);
			stream = convertChannels(nDesiredChannels, stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"stream: "</font> + stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"format: "</font> + stream.getFormat());
		}

		<font color="#B22222">/* Step 3: convert sample size and endianess, if necessary.
		*/</font>
		boolean bDoConvertSampleSize =
			(stream.getFormat().getSampleSizeInBits() != nDesiredSampleSizeInBits);
		boolean bDoConvertEndianess =
			(stream.getFormat().isBigEndian() != bDesiredBigEndian);
		<font color="#4169E1">if</font> (bDoConvertSampleSize || bDoConvertEndianess)
		{
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"converting sample size and endianess..."</font>);
			stream = convertSampleSizeAndEndianess(nDesiredSampleSizeInBits,
												   bDesiredBigEndian, stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"stream: "</font> + stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"format: "</font> + stream.getFormat());
		}

		<font color="#B22222">/* Step 4: convert sample rate, if necessary.
		*/</font>
		<font color="#4169E1">if</font> (! equals(stream.getFormat().getSampleRate(), fDesiredSampleRate))
		{
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"converting sample rate..."</font>);
			stream = convertSampleRate(fDesiredSampleRate, stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"stream: "</font> + stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"format: "</font> + stream.getFormat());
		}

		<font color="#B22222">/* Step 5: convert to non-PCM encoding, if necessary.
		*/</font>
		<font color="#4169E1">if</font> (! stream.getFormat().getEncoding().equals(desiredEncoding))
		{
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"converting to "</font> + desiredEncoding + <font color="#666666">"..."</font>);
			stream = convertEncoding(desiredEncoding, stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"stream: "</font> + stream);
			<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"format: "</font> + stream.getFormat());
		}

		<font color="#B22222">/* Since we now know that we are dealing with PCM, we know
		   that the frame rate is the same as the sample rate.
		*/</font>
<font color="#B22222">// 		float		fTargetFrameRate = fTargetSampleRate;</font>

<font color="#B22222">// 		/* Here, we are constructing the desired format of the</font>
<font color="#B22222">// 		   audio data (as the result of the conversion should be).</font>
<font color="#B22222">// 		   We take over all values besides the sample/frame rate.</font>
<font color="#B22222">// 		*/</font>

		<font color="#B22222">/* And finally, we are trying to write the converted audio
		   data to a new file.
		*/</font>
		int	nWrittenBytes = 0;
		AudioFileFormat.Type targetFileType = (desiredFileType != null) ?
			desiredFileType : defaultFileType;
		nWrittenBytes = AudioSystem.write(stream, targetFileType, outputFile);
		<font color="#4169E1">if</font> (DEBUG) out(<font color="#666666">"Written bytes: "</font> + nWrittenBytes);
	}



	private static AudioInputStream convertEncoding(
		AudioFormat.Encoding targetEncoding,
		AudioInputStream sourceStream)
	{
		<font color="#4169E1">return</font> AudioSystem.getAudioInputStream(targetEncoding,
											   sourceStream);
	}


<strong><font color="#4169E1">	private static AudioInputStream convertChannels(
		int nChannels,
		AudioInputStream sourceStream)</font></strong>
	{
		AudioFormat sourceFormat = sourceStream.getFormat();
		AudioFormat targetFormat = new AudioFormat(
			sourceFormat.getEncoding(),
			sourceFormat.getSampleRate(),
			sourceFormat.getSampleSizeInBits(),
			nChannels,
			calculateFrameSize(nChannels,
							   sourceFormat.getSampleSizeInBits()),
			sourceFormat.getFrameRate(),
			sourceFormat.isBigEndian());
		<font color="#4169E1">return</font> AudioSystem.getAudioInputStream(targetFormat,
											   sourceStream);
	}


<strong><font color="#4169E1">	private static AudioInputStream convertSampleSizeAndEndianess(
		int nSampleSizeInBits,
		boolean bBigEndian,
		AudioInputStream sourceStream)</font></strong>
	{
		AudioFormat sourceFormat = sourceStream.getFormat();
		AudioFormat targetFormat = new AudioFormat(
			sourceFormat.getEncoding(),
			sourceFormat.getSampleRate(),
			nSampleSizeInBits,
			sourceFormat.getChannels(),
			calculateFrameSize(sourceFormat.getChannels(),
							   nSampleSizeInBits),
			sourceFormat.getFrameRate(),
			bBigEndian);
		<font color="#4169E1">return</font> AudioSystem.getAudioInputStream(targetFormat,
											   sourceStream);
	}


<strong><font color="#4169E1">	private static AudioInputStream convertSampleRate(
		float fSampleRate,
		AudioInputStream sourceStream)</font></strong>
	{
		AudioFormat sourceFormat = sourceStream.getFormat();
		AudioFormat targetFormat = new AudioFormat(
			sourceFormat.getEncoding(),
			fSampleRate,
			sourceFormat.getSampleSizeInBits(),
			sourceFormat.getChannels(),
			sourceFormat.getFrameSize(),
			fSampleRate,
			sourceFormat.isBigEndian());
		<font color="#4169E1">return</font> AudioSystem.getAudioInputStream(targetFormat,
											   sourceStream);
	}


<strong><font color="#4169E1">	private static int calculateFrameSize(int nChannels, int nSampleSizeInBits)</font></strong>
	{
		<font color="#4169E1">return</font> ((nSampleSizeInBits + 7) / 8) * nChannels;
	}


	<font color="#B22222">/** Compares two float values for equality.
	 */</font>
<strong><font color="#4169E1">	private static boolean equals(float f1, float f2)</font></strong>
	{
		<font color="#4169E1">return</font> (Math.abs(f1 - f2) &lt; DELTA);
	}



<strong><font color="#4169E1">	private static void printUsageAndExit()</font></strong>
	{
		out(<font color="#666666">"AudioConverter: usage:"</font>);
		out(<font color="#666666">"\tjava AudioConverter -h"</font>);
		out(<font color="#666666">"\tjava AudioConverter -l"</font>);
		out(<font color="#666666">"\tjava AudioConverter"</font>);
		out(<font color="#666666">"\t\t[-c &lt;channels&gt;]"</font>);
		out(<font color="#666666">"\t\t[-s &lt;sample_size_in_bits&gt;]"</font>);
		out(<font color="#666666">"\t\t[-e &lt;encoding&gt;]"</font>);
		out(<font color="#666666">"\t\t[-f &lt;sample_rate&gt;]"</font>);
		out(<font color="#666666">"\t\t[-t &lt;file_type&gt;]"</font>);
		out(<font color="#666666">"\t\t[-B|-L] [-D]"</font>);
		out(<font color="#666666">"\t\t&lt;sourcefile&gt; &lt;targetfile&gt;"</font>);
		System.exit(1);
	}



<strong><font color="#4169E1">	private static void out(String strMessage)</font></strong>
	{
		System.out.println(strMessage);
	}
}



<font color="#B22222">/*** AudioConverter.java ***/</font>

</pre>
</body>

</html>
